home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 424_01 / ed_157 / ttyput.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-28  |  34.8 KB  |  1,379 lines

  1. /*
  2.  * Copyright (C) 1992 by Rush Record
  3.  * Copyright (C) 1993 by Charles Sandmann (sandmann@clio.rice.edu)
  4.  * 
  5.  * This file is part of ED.
  6.  * 
  7.  * ED is free software; you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation.
  9.  * 
  10.  * ED is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  11.  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12.  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  13.  * 
  14.  * You should have received a copy of the GNU General Public License along with ED
  15.  * (see the file COPYING).  If not, write to the Free Software Foundation, 675
  16.  * Mass Ave, Cambridge, MA 02139, USA.
  17.  */
  18. #include "opsys.h"
  19.  
  20. #include <stdio.h>
  21. #include <string.h>
  22.  
  23. extern void cleanup();
  24. static Int restored = 1;    /* flag to control behavior of ttyend(). it does restoration only if restored == 0. */
  25.  
  26. #ifdef VMS
  27. #include <ssdef.h>
  28. #include <ttdef.h>
  29. #include <iodef.h>
  30.  
  31. static short chan = 0;
  32. extern void ttyend();
  33. static int desblk[4] = {0,(int)ttyend,0,(int)&desblk[3]};
  34. static Char sysinput[] = {"SYS$COMMAND"};
  35. static struct {unsigned short length,class;Char *string;} desc = {11,0x010e,sysinput};
  36. typedef struct mode_str *mode_ptr;
  37. typedef struct mode_str
  38. {
  39.     Uchar class,type;
  40.     unsigned short buffersize;
  41.     union
  42.     {
  43.         unsigned int characteristics;
  44.         Uchar page[4];
  45.     } u;
  46.     unsigned int extended;
  47. } mode_node;
  48. static mode_node old_mode;
  49. static unsigned int newmask = 0x02100000,oldmask;    /* disable interrupts */
  50. static Char ctrlc_typed = 0;
  51.  
  52. /******************************************************************************\
  53. |Routine: ttysetsize
  54. |Callby: init_term
  55. |Purpose: Handles defaults for terminal size.
  56. |Arguments:
  57. |    NROW,NCOL - the number of rows and columns on the screen.
  58. \******************************************************************************/
  59. void ttysetsize(nrow,ncol)
  60. Int *nrow,*ncol;
  61. {
  62.     unsigned short tmprow, tmpcol;
  63.  
  64.     if(!*nrow || !*ncol)
  65.     {
  66.         tmprow = 24;
  67.         tmpcol = 80;
  68.         if(old_mode.class == 66) /* Terminal */
  69.         {
  70.             if(old_mode.u.page[3] > 1)
  71.                 tmprow = old_mode.u.page[3];
  72.             tmpcol = old_mode.buffersize;
  73.         }
  74.         if(!*nrow)
  75.             *nrow = tmprow;
  76.         if(!*ncol)
  77.             *ncol = tmpcol;
  78.     }
  79.  
  80. }
  81.  
  82. /******************************************************************************\
  83. |Routine: ttygetsb
  84. |Callby: put
  85. |Purpose: Null routine.
  86. |Arguments:
  87. |    ptr - physical video frame buffer base pointer.
  88. \******************************************************************************/
  89. void ttygetsb(ptr)
  90. short **ptr;
  91. {
  92.     printf("You can't use this terminal configuration file with this image.\r\n");
  93.     cleanup(-1);
  94. }
  95.  
  96. /******************************************************************************\
  97. |Routine: ttyscreen
  98. |Callby: put
  99. |Purpose: Null routine.
  100. |Arguments:
  101. |    row, col - where to position the cursor on the screen, zero based.
  102. \******************************************************************************/
  103. void ttyscreen(row,col)
  104. Int row,col;
  105. {
  106. }
  107.  
  108. /******************************************************************************\
  109. |Routine: ring_bell
  110. |Callby: init_term
  111. |Purpose: Handles special bell-ringing for brain-dead terminals.
  112. |Arguments:
  113. |    none
  114. \******************************************************************************/
  115. void ring_bell()
  116. {
  117. }
  118.  
  119. /******************************************************************************\
  120. |Routine: ttyend
  121. |Callby: init_term ttyput
  122. |Purpose: Terminates connection with the terminal.
  123. |Arguments:
  124. |    none
  125. \******************************************************************************/
  126. void ttyend()
  127. {
  128.     unsigned short iosb[4],temp;
  129.     
  130.     if(temp = chan)
  131.     {
  132.         chan = 0;
  133.         SYS$CANEXH(desblk);
  134.         SYS$QIOW(0,temp,IO$_SETMODE,iosb,0,0,&old_mode,12,0,0,0,0);
  135.         SYS$DASSGN(temp);
  136.         LIB$ENABLE_CTRL(&oldmask);
  137.     }
  138. }
  139.  
  140. /******************************************************************************\
  141. |Routine: ttyioerr
  142. |Callby: ttyput
  143. |Purpose: Handles i/o errors with the terminal.
  144. |Arguments:
  145. |    status is the VMS status of the i/o.
  146. |    iosb is the VMS i/o status block.
  147. \******************************************************************************/
  148. void ttyioerr(status,iosb)
  149. Int status;
  150. unsigned short iosb;
  151. {
  152.     if(!(status & 1))
  153.     {
  154.         if(status != SS$_TIMEOUT)
  155.             goto report_error;
  156.     }
  157.     else
  158.     {
  159.         if(!((status = iosb) & 1))
  160.         {
  161.             if(status != SS$_TIMEOUT)
  162.                 goto report_error;
  163.         }
  164.     }
  165.     return;
  166. report_error: 
  167.     printf("An I/O error occurred (error #%08X).\r\n",status);
  168.     cleanup(-1);
  169. }
  170.  
  171. /******************************************************************************\
  172. |Routine: ttyput
  173. |Callby: put
  174. |Purpose: Puts characters to the terminal.
  175. |Arguments:
  176. |    c is the string to send to the terminal.
  177. \******************************************************************************/
  178. void ttyput(c)
  179. Char *c;
  180. {
  181.     Int i,status;
  182.     unsigned short iosb[4];
  183.  
  184.     if(!(i = strlen(c)))
  185.         return;
  186.     while(i > 64)
  187.     {
  188.         status = SYS$QIOW(0,chan,IO$_WRITEVBLK | IO$M_NOFORMAT,iosb,0,0,c,64,0,0,0,0);
  189.         ttyioerr(status,iosb[0]);
  190.         c += 64;
  191.         i -= 64;
  192.     }
  193.     if(i)
  194.     {
  195.         status = SYS$QIOW(0,chan,IO$_WRITEVBLK | IO$M_NOFORMAT,iosb,0,0,c,i,0,0,0,0);
  196.         ttyioerr(status,iosb[0]);
  197.     }
  198. }
  199.  
  200. /******************************************************************************\
  201. |Routine: ttychk
  202. |Callby: load_file
  203. |Purpose: Null routine.
  204. |Arguments:
  205. |    none
  206. \******************************************************************************/
  207. Int ttychk()
  208. {
  209.     if(ctrlc_typed)
  210.     {
  211.         ctrlc_typed = 0;
  212.         return(3);
  213.     }
  214.     return(0);
  215. }
  216.  
  217. /******************************************************************************\
  218. |Routine: setctrlc
  219. |Callby: ttystart
  220. |Purpose: AST routine to set the ctrlc-has-been-typed flag.
  221. |Arguments:
  222. |    none
  223. \******************************************************************************/
  224. void setctrlc()
  225. {
  226.     unsigned short iosb[4];
  227.     
  228.     ctrlc_typed = 1;
  229.     SYS$QIOW(0,chan,IO$_SETMODE | IO$M_CTRLCAST,iosb,0,0,setctrlc,0,0,0,0,0);
  230. }
  231.  
  232. /******************************************************************************\
  233. |Routine: ttyget
  234. |Callby: cfg init_term
  235. |Purpose: Gets a character from the terminal.
  236. |Arguments:
  237. |    c is the returned character.
  238. \******************************************************************************/
  239. void ttyget(c)
  240. Schar *c;
  241. {
  242.     static Char buf[128],*next = buf;
  243.     static int terms[8] = {0,0,0,0,0,0,0,0};
  244.     static struct {int nbytes,*terminators;} term_desc = {0,terms};
  245.     static Int remain = 0;
  246.     Int status;
  247.     unsigned short iosb[4];
  248.  
  249.     if(!remain)
  250.     {
  251.         status = SYS$QIOW(0,chan,IO$_TTYREADALL | IO$M_NOECHO | IO$M_NOFILTR | IO$M_TIMED,iosb,0,0,buf,sizeof(buf) - 3,0,&term_desc,0,0);
  252.         ttyioerr(status,iosb[0]);
  253.         if(!(remain = iosb[1]))
  254.         {
  255.             status = SYS$QIOW(0,chan,IO$_TTYREADALL | IO$M_NOECHO,iosb,0,0,c,1,0,0,0,0);
  256.             ttyioerr(status,iosb[0]);
  257.             return;
  258.         }
  259.         else
  260.             next = buf;
  261.     }
  262.     *c = *((Schar *)next++);
  263.     remain--;
  264. }
  265.  
  266. /******************************************************************************\
  267. |Routine: ttystart
  268. |Callby: init_term
  269. |Purpose: Initializes communication with the terminal.
  270. |Arguments:
  271. |    none
  272. \******************************************************************************/
  273. void ttystart()
  274. {
  275.     mode_node new_mode;
  276.     Int status;
  277.     unsigned short iosb[4];
  278.  
  279.     if(!chan)
  280.     {
  281.         LIB$DISABLE_CTRL(&newmask,&oldmask);
  282.         status = SYS$ASSIGN(&desc,&chan,0,0);
  283.         if(!(status & 1))
  284.         {
  285.             printf("Unable to assign a channel to SYS$COMMAND (error #%08X).\r\n",status);
  286.             exit(-1);
  287.         }
  288.         old_mode.class = 0;            /* Just in case it fails */
  289.         SYS$QIOW(0,chan,IO$_SENSEMODE,iosb,0,0,&old_mode,12,0,0,0,0);
  290.         new_mode = old_mode;
  291.         new_mode.u.characteristics |= TT$M_HOSTSYNC|TT$M_TTSYNC|TT$M_NOBRDCST|TT$M_NOECHO;
  292.         SYS$QIOW(0,chan,IO$_SETMODE,iosb,0,0,&new_mode,12,0,0,0,0);
  293.         if(!((status = SYS$DCLEXH(desblk)) & 1))
  294.         {
  295.             ttyend();
  296.             printf("Unable to declare exit handler, status = %08X\n",status);
  297.             cleanup(0);
  298.         }
  299.         SYS$QIOW(0,chan,IO$_SETMODE | IO$M_CTRLCAST,iosb,0,0,setctrlc,0,0,0,0,0);
  300.     }
  301. }
  302.  
  303. #else    /* VMS */
  304.  
  305. #ifdef WIN32    /* Windows NT */
  306. #include <windows.h>
  307.  
  308. static short *screen_base = 0;        /* pointer to PC screen area */
  309. static CHAR_INFO *pchar_base = 0;    /* pointer to pchiSrcBuffer */
  310. static unsigned short lenLVB = 0;    /* length of screen */
  311. static COORD coordScreen;            /* Size of Screen */
  312. static HANDLE hOut,hIn;                /* Screen & Keyboard Handles */
  313. static DWORD dwMode;                /* terminal input settings */
  314.  
  315. /******************************************************************************\
  316. |Routine: ttygetsb
  317. |Callby: put
  318. |Purpose: Returns video buffer base.
  319. |Arguments:
  320. |    ptr - logical video frame buffer base pointer.
  321. \******************************************************************************/
  322. void ttygetsb(ptr)
  323. short **ptr;
  324. {
  325.     *ptr = screen_base;
  326. }
  327.  
  328. /******************************************************************************\
  329. |Routine: ttysetsize
  330. |Callby: init_term
  331. |Purpose: Handles defaults for terminal size.
  332. |Arguments:
  333. |    nrow, ncol - the number of rows and columns on the screen.
  334. \******************************************************************************/
  335. void ttysetsize(nrow,ncol)
  336. Int *nrow,*ncol;
  337. {
  338.     CONSOLE_SCREEN_BUFFER_INFO csbi;
  339.     BOOL bSuccess;
  340.  
  341.     hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  342.     if(hOut == INVALID_HANDLE_VALUE)
  343.     {
  344.         printf("GetStdHandle failed %x\n",GetLastError());
  345.         cleanup(-1);
  346.     }
  347.  
  348. /* Screen resizing not implemented - to be done */
  349. /*    bSuccess = GetConsoleScreenBufferInfo(hOut,&csbi);
  350.     change = 0;
  351.     if(*ncol > csbi.dwSize.X)
  352.     {
  353.         change = 1;
  354.         coordScreen.X = *ncol;
  355.     } else
  356.         coordScreen.X = csbi.dwSize.X;
  357.     if(*nrow > csbi.dwSize.Y)
  358.     {
  359.         change = 1;
  360.         coordScreen.Y = *nrow;
  361.     } else
  362.         coordScreen.Y = csbi.dwSize.Y;
  363.     if(change)
  364.     {
  365.         bSuccess = SetConsoleScreenBufferInfo(hOut,&coordScreen);
  366.     }
  367.     */
  368.     bSuccess = GetConsoleScreenBufferInfo(hOut,&csbi);
  369.     if(!bSuccess)
  370.     {
  371.         printf("GetConsoleScreenBufferInfo failed %x\n",GetLastError());
  372.         csbi.dwSize.X = 80;
  373.         csbi.dwSize.Y = 25;
  374.     }
  375.     *ncol = coordScreen.X = csbi.dwSize.X;
  376.     *nrow = coordScreen.Y = csbi.dwSize.Y;
  377.  
  378.     lenLVB = *nrow * *ncol;
  379.     screen_base = (short *)imalloc(lenLVB * sizeof(short));
  380.     pchar_base = (CHAR_INFO *)imalloc(lenLVB * sizeof(CHAR_INFO));
  381. }
  382.  
  383. /******************************************************************************\
  384. |Routine: ttyscreen
  385. |Callby: put
  386. |Purpose: Updates screen buffer and positions cursor (BRAINDEAD only).
  387. |Arguments:
  388. |    row, col - where to position the cursor on the screen, zero based.
  389. \******************************************************************************/
  390. void ttyscreen(row,col)
  391. Int row,col;
  392. {
  393.     int i;
  394.     COORD coord;
  395.     SMALL_RECT srec;
  396.  
  397.     for(i = 0;i < lenLVB;i++)
  398.     {
  399.         pchar_base[i].Char.AsciiChar = screen_base[i] & 0xff;
  400.         pchar_base[i].Attributes = screen_base[i] >> 8;
  401.     }
  402.     coord.X = coord.Y = 0;
  403.     srec.Left = srec.Top = 0;
  404.     srec.Right = coordScreen.X - 1;
  405.     srec.Bottom = coordScreen.Y - 1;
  406.     if(!WriteConsoleOutput(hOut,pchar_base,coordScreen,coord,&srec))
  407.     {
  408.         printf("WriteConsoleOutput failed %x\n",GetLastError());
  409.         cleanup(-1);
  410.     }
  411.     coord.X = col;
  412.     coord.Y = row;
  413.     if(!SetConsoleCursorPosition(hOut,coord))
  414.     {
  415.         printf("SetConsoleCursorPosition failed %x\n",GetLastError());
  416.         cleanup(-1);
  417.     }
  418. }
  419.  
  420. /******************************************************************************\
  421. |Routine: ring_bell
  422. |Callby: init_term
  423. |Purpose: Handles special bell-ringing for BRAINDEAD terminals.
  424. |Arguments:
  425. |    none
  426. \******************************************************************************/
  427. void ring_bell()
  428. {
  429.     Beep(320,100);
  430. }
  431.  
  432. /******************************************************************************\
  433. |Routine: ttyput
  434. |Callby: put
  435. |Purpose: Puts characters to the terminal.
  436. |Arguments:
  437. |    c is the string to send to the terminal.
  438. \******************************************************************************/
  439. void ttyput(c)
  440. Char *c;
  441. {
  442. }
  443.  
  444. /******************************************************************************\
  445. |Routine: ttychk
  446. |Callby: load_file
  447. |Purpose: Null routine.
  448. |Arguments:
  449. |    none
  450. \******************************************************************************/
  451. Int ttychk()
  452. {
  453.     return(0);
  454. }
  455.  
  456. /******************************************************************************\
  457. |Routine: ttyget
  458. |Callby: cfg init_term
  459. |Purpose: Gets a character from the terminal.
  460. |Arguments:
  461. |    c is the returned character.
  462. \******************************************************************************/
  463. void ttyget(c)
  464. Schar *c;
  465. {
  466.     static Char buf[2],*next = buf;
  467.     static Int remain = 0;
  468.     short shift;
  469.     Int evtcode,scan,asci;
  470.     Uchar thischar;
  471.     INPUT_RECORD pirBuf;
  472.     DWORD nr;    /* number of events actually read */
  473.  
  474.     while(!remain)
  475.     {
  476.         next = buf;
  477.  
  478.         do
  479.             if(!ReadConsoleInput(hIn,&pirBuf,1,&nr))
  480.             {
  481.                 printf("ReadConsoleInput failed %x\n",GetLastError());
  482.                 cleanup(-1);
  483.             }
  484.         while(pirBuf.EventType != KEY_EVENT || !pirBuf.Event.KeyEvent.bKeyDown);
  485.  
  486.         shift = pirBuf.Event.KeyEvent.dwControlKeyState;
  487.         scan = pirBuf.Event.KeyEvent.wVirtualScanCode;
  488.         asci = pirBuf.Event.KeyEvent.uChar.AsciiChar;
  489.  
  490.         evtcode = (scan << 8) | asci;
  491.         if(evtcode == 0x0e08)
  492.             thischar = 127;        /* Rubout */
  493.         else if(evtcode == 0x352f && shift & ENHANCED_KEY)
  494.             thischar = 0xbe;    /* PF2 fixup */
  495.         else if(evtcode == 0x1c0d && shift & ENHANCED_KEY)
  496.             thischar = 0xbd;    /* KpEnter */
  497.         else if( (asci > 0) && (scan <= 0x35) )
  498.         {
  499.             /* If Caps Lock on then it is Caps! */
  500.             if((CAPSLOCK_ON & shift) && 
  501.                 (asci >= 'a') && (asci <= 'z') )
  502.                     asci = asci - 0x20;
  503.             thischar = asci;
  504.         }
  505.         else if(scan == 0x39)
  506.             thischar = ' ';        /* Space */
  507.         /* 13 characters between 0x00 and 0x0c (Keypad & Arrows) */
  508.         else if( (scan >= 0x47) && (scan <= 0x53) )
  509.         {
  510.             if( shift & ENHANCED_KEY )
  511.                 thischar = 0xa0 + (scan - 0x47);
  512.             else
  513.                 thischar = 0xb0 + (scan - 0x47);
  514.         }
  515.         else if( evtcode == 0x372a )
  516.             thischar = 0xbf;    /* PF3 */
  517.         else if( evtcode == 0x0300 )
  518.             thischar = 0;        /* Null */
  519.         /* 10 characters between 0x00 and 0x09 (F1 to F10) */
  520.         else if( (scan >= 0x3b) && (scan <= 0x44) )
  521.             thischar = 0xc0 + (scan - 0x3b);
  522.         else if( evtcode == 0x5700 ) /* 8500 */
  523.             thischar = 0xca;    /* F11 */
  524.         else if( evtcode == 0x5800 ) /* 8600 */
  525.             thischar = 0xcb;    /* F12 */
  526.         else if( evtcode == 0x4500 )
  527.             thischar = 0xaf;    /* NumLock = GOLD */
  528.         else
  529.             thischar = 0xff;        /* indicate not set */
  530.  
  531.         if(thischar >= 0xb0 && thischar <= 0xbf) /* shift special */
  532.             if(SHIFT_PRESSED & shift) thischar -= 0x10;
  533.  
  534.         if(thischar != 0xff)
  535.         {
  536.             *next++ = thischar;
  537.             remain++;
  538.         }
  539.         next = buf;
  540.     }
  541.     *c = *((Schar *)next++);
  542.     remain--;
  543.     return;
  544. }
  545.  
  546. /******************************************************************************\
  547. |Routine: ttyend
  548. |Callby: init_term
  549. |Purpose: Terminates connection with the terminal.
  550. |Arguments:
  551. |    none
  552. \******************************************************************************/
  553. void ttyend()    /* this is a handler that restores the terminal settings at image exit */
  554. {
  555.     if(restored++)
  556.         return;
  557.     if(!SetConsoleMode(hIn,dwMode))
  558.     {
  559.         printf("SetConsoleMode failed %x\n",GetLastError());
  560.     }
  561.     return;
  562. }
  563.  
  564. /******************************************************************************\
  565. |Routine: ttystart
  566. |Callby: init_term
  567. |Purpose: Initializes communication with the terminal.
  568. |Arguments:
  569. |    none
  570. \******************************************************************************/
  571. void ttystart()
  572. {
  573.     hIn = GetStdHandle(STD_INPUT_HANDLE);
  574.     if(hIn == INVALID_HANDLE_VALUE)
  575.     {
  576.         printf("GetStdHandle failed %x\n",GetLastError());
  577.         cleanup(-1);
  578.     }
  579.     if(!GetConsoleMode(hIn,&dwMode))
  580.     {
  581.         printf("GetConsoleMode failed %x\n",GetLastError());
  582.         cleanup(-1);
  583.     }
  584.     if(!SetConsoleMode(hIn,(dwMode & ~(ENABLE_LINE_INPUT |
  585.         ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT |
  586.         ENABLE_PROCESSED_INPUT |ENABLE_WINDOW_INPUT) )) )
  587.     {
  588.         printf("SetConsoleMode failed %x\n",GetLastError());
  589.         cleanup(-1);
  590.     }
  591.     restored = 0;
  592. }
  593.  
  594. #else        /* !WIN32 */
  595.  
  596. #ifdef GNUOS2
  597. #define  INCL_KBD        /* Define Kbd routines in os2.h */
  598. #define  INCL_VIO        /* Define Vio routines in os2.h */
  599. #define  INCL_NOPM        /* Don't define PM routines in os2.h */
  600. #include <os2.h>
  601. static short *screen_base = 0;    /* pointer to PC screen area */
  602. static short saveshift = 0;    /* shift flags from previous keystroke */
  603. static unsigned short lenLVB = 0; /* length of screen */
  604.  
  605. /******************************************************************************\
  606. |Routine: ttygetsb
  607. |Callby: put
  608. |Purpose: Returns video buffer base.
  609. |Arguments:
  610. |    ptr - logical video frame buffer base pointer.
  611. \******************************************************************************/
  612. void ttygetsb(ptr)
  613. short **ptr;
  614. {
  615.     *ptr = screen_base;
  616. }
  617.  
  618. /******************************************************************************\
  619. |Routine: ttysetsize
  620. |Callby: init_term
  621. |Purpose: Handles defaults for terminal size.
  622. |Arguments:
  623. |    nrow, ncol - the number of rows and columns on the screen.
  624. \******************************************************************************/
  625. void ttysetsize(nrow,ncol)
  626. Int *nrow,*ncol;
  627. {
  628.     VIOMODEINFO viomi;
  629.  
  630.     viomi.cb = sizeof(viomi);
  631.     VioGetMode(&viomi, 0);
  632.  
  633.     if(*ncol > viomi.col)        /* User wants more columns, set to 132 (max) */
  634.     {
  635. /*        viomi.col = 132; 
  636.         VioSetMode(&viomi, 0);
  637.         VioGetMode(&viomi, 0); */
  638.     }
  639.  
  640.     if(*nrow > viomi.row)        /* User wants more rows, use 8x8 font */
  641.     {
  642. /*        viomi.row = *nrow; */
  643.         viomi.row = 50;
  644.         VioSetMode(&viomi, 0);
  645.         VioGetMode(&viomi, 0);
  646.     }
  647.  
  648.     /* Indicate final resolution (may or may not change from above) */
  649.     *nrow = viomi.row;
  650.     *ncol = viomi.col;
  651.     lenLVB = viomi.row * viomi.col * sizeof(short);
  652.     screen_base = (short *)imalloc(lenLVB);
  653. }
  654.  
  655. /******************************************************************************\
  656. |Routine: ttyscreen
  657. |Callby: put
  658. |Purpose: Updates screen buffer and positions cursor (DOS & OS2 only).
  659. |Arguments:
  660. |    row, col - where to position the cursor on the screen, zero based.
  661. \******************************************************************************/
  662. void ttyscreen(row,col)
  663. Int row,col;
  664. {
  665.     short i;
  666.     
  667.     if((i = VioWrtCellStr((Char *)screen_base, lenLVB, 0, 0, 0)))
  668.     {
  669.         printf("VioWrtCellStr failure %d.\n",i);
  670.         cleanup(-1);
  671.     }
  672.         
  673.     if((i = VioSetCurPos((unsigned short)row, (unsigned short)col, 0)))
  674.     {
  675.         printf("VioSetCurPos failure %d.\n",i);
  676.         cleanup(-1);
  677.     }
  678. }
  679.  
  680. /******************************************************************************\
  681. |Routine: ring_bell
  682. |Callby: init_term
  683. |Purpose: Handles special bell-ringing for non-terminal PC terminals.
  684. |Arguments:
  685. |    none
  686. \******************************************************************************/
  687. void ring_bell()
  688. {
  689.     DosBeep(320,100);
  690. }
  691.  
  692. /******************************************************************************\
  693. |Routine: ttyput
  694. |Callby: put
  695. |Purpose: Puts characters to the terminal.
  696. |Arguments:
  697. |    c is the string to send to the terminal.
  698. \******************************************************************************/
  699. void ttyput(c)
  700. Char *c;
  701. {
  702. }
  703.  
  704. /******************************************************************************\
  705. |Routine: ttychk
  706. |Callby: load_file
  707. |Purpose: Null routine.
  708. |Arguments:
  709. |    none
  710. \******************************************************************************/
  711. Int ttychk()
  712. {
  713.     return(0);
  714. }
  715.  
  716. /******************************************************************************\
  717. |Routine: ttyget
  718. |Callby: cfg init_term
  719. |Purpose: Gets a character from the terminal.
  720. |Arguments:
  721. |    c is the returned character.
  722. \******************************************************************************/
  723. void ttyget(c)
  724. Schar *c;
  725. {
  726.     static Char buf[2],*next = buf;
  727.     static Int remain = 0;
  728.     short shift;
  729.     Int evtcode,scan,asci;
  730.     Uchar thischar;
  731.     KBDKEYINFO keyinf;
  732.  
  733.     while(!remain)
  734.     {
  735.         next = buf;
  736.         if(KbdCharIn(&keyinf, IO_WAIT, 0))
  737.         {
  738.             printf("KbdCharIn failed!\n");
  739.             cleanup(-1);
  740.         }
  741.         shift = keyinf.fsState;
  742.         if(NUMLOCK_ON & (shift ^ saveshift))
  743.         {
  744.             *next++ = 0xaf;        /* NumLock */
  745.             remain++;
  746.         }
  747.         saveshift = shift;
  748.         evtcode = (keyinf.chScan << 8) | keyinf.chChar;
  749.         scan = keyinf.chScan;
  750.         asci = keyinf.chChar;
  751.         if( evtcode == 0x0e08 )
  752.             thischar = 127;        /* Rubout */
  753.         else if( (asci > 0) && (scan <= 0x35) )
  754.         {
  755.             /* If Caps Lock on then it is Caps! */
  756.             if((CAPSLOCK_ON & shift) && 
  757.                 (asci >= 'a') && (asci <= 'z') )
  758.                     asci = asci - 0x20;
  759.             thischar = asci;
  760.         }
  761.         else if( scan == 0x39)
  762.             thischar = ' ';        /* Space */
  763.         /* 13 characters between 0x00 and 0x0c (Keypad & Arrows) */
  764.         else if( (scan >= 0x47) && (scan <= 0x53) )
  765.         {
  766.             if( asci == 0xe0 )
  767.                 thischar = 0xa0 + (scan - 0x47);
  768.             else
  769.                 thischar = 0xb0 + (scan - 0x47);
  770.         }
  771.         else if( evtcode == 0xe00d )
  772.             thischar = 0xbd;    /* KpEnter */
  773.         else if( evtcode == 0xe02f )
  774.             thischar = 0xbe;    /* PF2 */
  775.         else if( evtcode == 0x372a )
  776.             thischar = 0xbf;    /* PF3 */
  777.         else if( evtcode == 0x0300 )
  778.             thischar = 0;        /* Null */
  779.         /* 10 characters between 0x00 and 0x09 (F1 to F10) */
  780.         else if( (scan >= 0x3b) && (scan <= 0x44) )
  781.             thischar = 0xc0 + (scan - 0x3b);
  782.         else if( evtcode == 0x8500 )
  783.             thischar = 0xca;    /* F11 */
  784.         else if( evtcode == 0x8600 )
  785.             thischar = 0xcb;    /* F12 */
  786.         else
  787.             thischar = 0xff;        /* indicate not set */
  788.  
  789.         if(thischar >= 0xb0 && thischar <= 0xbf) /* shift special */
  790.             if(KB_SHIFT & shift) thischar -= 0x10;
  791.  
  792.         if(thischar != 0xff)
  793.         {
  794.             *next++ = thischar;
  795.             remain++;
  796.         }
  797.         next = buf;
  798.     }
  799.     *c = *((Schar *)next++);
  800.     remain--;
  801.     return;
  802. }
  803.  
  804. /******************************************************************************\
  805. |Routine: ttyend
  806. |Callby: init_term ttyput
  807. |Purpose: Terminates connection with the terminal.
  808. |Arguments:
  809. |    none
  810. \******************************************************************************/
  811. void ttyend()    /* this is a handler that restores the terminal settings at image exit */
  812. {
  813.     if(restored++)
  814.         return;
  815.     return;
  816. }
  817.  
  818. void ttystart()
  819. {
  820.     KBDINFO kbstInfo;
  821.  
  822.     kbstInfo.cb = sizeof(kbstInfo);        /* Length of status buffer */
  823.     if(KbdGetStatus(&kbstInfo, 0))
  824.     {
  825.         printf("KbdGetStatus failed!\n");
  826.         cleanup(-1);
  827.     }
  828.     saveshift = kbstInfo.fsState;
  829.     restored = 0;
  830. }
  831.  
  832. #else        /* !GNUOS2 */
  833.  
  834. #ifdef GNUDOS
  835. #include <stdlib.h>
  836. #include <pc.h>
  837. #include <dos.h>
  838. #ifndef NO_EVENTS        /* Define this if you don't have cbgrx*.zip */
  839. #include <eventque.h>
  840.  
  841. #define Qsize 100        /* number of interrupt events to queue */
  842. EventQueue *q = 0;
  843. #else
  844. #define KB_NUMLOCK    0x20        /* NUM LOCK active */
  845. #define KB_CAPSLOCK    0x40        /* CAPS LOCK active */
  846. #define KB_SHIFT    0x03        /* Either shift key depressed */
  847. #endif
  848.  
  849. static short *screen_base = NULL;
  850. static short saveshift = 0;    /* shift flags from previous keystroke */
  851. static char setnumlk = 1;    /* reset NumLock */
  852. static int direct_access = 0;    /* Can we directly touch hardware? */
  853.  
  854. /******************************************************************************\
  855. |Routine: ttygetsb
  856. |Callby: put
  857. |Purpose: Returns video buffer base.
  858. |Arguments:
  859. |    ptr - physical video frame buffer base pointer.
  860. \******************************************************************************/
  861. void ttygetsb(ptr)
  862. short **ptr;
  863. {
  864.     *ptr = screen_base;
  865. }
  866.  
  867. /******************************************************************************\
  868. |Routine: ttyscreen
  869. |Callby: put
  870. |Purpose: Updates screen buffer and positions cursor (DOS & OS2 only).
  871. |Arguments:
  872. |    row, col - where to position the cursor on the screen, zero based.
  873. \******************************************************************************/
  874. void ttyscreen(row,col)
  875. Int row,col;
  876. {
  877.     if(!direct_access)        /* then protected mode, copy LVB */
  878.         ScreenUpdate(screen_base);
  879.     ScreenSetCursor(row,col);
  880. }
  881.  
  882. /******************************************************************************\
  883. |Routine: ttysetsize
  884. |Callby: init_term
  885. |Purpose: Handles defaults for terminal size.
  886. |Arguments:
  887. |    NROW,NCOL - the number of rows and columns on the screen.
  888. \******************************************************************************/
  889. void ttysetsize(nrow,ncol)
  890. Int *nrow,*ncol;
  891. {
  892.     Uchar pcrow,pccol;
  893.     union REGS regs;
  894.     char *numlkt;
  895.  
  896.     pcrow = ScreenRows();
  897.     pccol = ScreenCols();
  898.  
  899.     if(*ncol > pccol)        /* User wants more columns, set to 132 (max) */
  900.     {
  901.         regs.x.ax = 0x23;        /* Try Pro II 132x25 mode */
  902.         int86(0x10, ®s, ®s);
  903.     }
  904.  
  905.     if(*nrow > pcrow)        /* User wants more rows, use 8x8 font */
  906.     {
  907.         regs.x.ax = 0x1202;
  908.         regs.x.bx = 0x30;
  909.         int86(0x10, ®s, ®s);    /* Set 400 scan lines */
  910.  
  911.         regs.x.ax = 0x1112;
  912.         regs.x.bx = 0;
  913.         int86(0x10, ®s, ®s);    /* Set font and reprogram */
  914.     }
  915.  
  916.     /* Indicate final resolution (may or may not change from above) */
  917.     *nrow = ScreenRows();
  918.     *ncol = ScreenCols();
  919.  
  920.     /* Check for DPMI (ESP will be small) */
  921.     asm volatile(                               "\n\
  922.         movl   %%esp,%%eax                        \n\
  923.         andl   $0x40000000,%%eax                    \n\
  924.         movl   %%eax,_direct_access                    "
  925.         : : : "ax"
  926.     );
  927.  
  928.     if(direct_access)        /* direct access OK */
  929.         screen_base = ScreenPrimary;    /* From pc.h (short *)0xe00b8000L; */
  930.     else                        /* Protected mode need buffer */
  931.         screen_base = (short *)imalloc( *nrow * *ncol * sizeof(short) );
  932.  
  933.     if((numlkt = getenv("ED_NUMLK")) && *numlkt == 'N') setnumlk = 0;
  934. }
  935.  
  936. /******************************************************************************\
  937. |Routine: ring_bell
  938. |Callby: init_term
  939. |Purpose: Handles special bell-ringing for non-terminal PC terminals.
  940. |Arguments:
  941. |    none
  942. \******************************************************************************/
  943. void ring_bell()
  944. {
  945.     sound(320);            /* Frequency 320 Hz */
  946.     delay(100);            /* 100 ms duration */
  947.     nosound();
  948. }
  949.  
  950. /******************************************************************************\
  951. |Routine: ttyput
  952. |Callby: put
  953. |Purpose: Null routine.
  954. |Arguments:
  955. |    c is the string to send to the terminal.
  956. \******************************************************************************/
  957. void ttyput(c)
  958. Char *c;
  959. {
  960. }
  961.  
  962. /******************************************************************************\
  963. |Routine: ttychk
  964. |Callby: load_file
  965. |Purpose: Null routine.
  966. |Arguments:
  967. |    none
  968. \******************************************************************************/
  969. Int ttychk()
  970. {
  971.     return(0);
  972. }
  973.  
  974. /******************************************************************************\
  975. |Routine: ttyget
  976. |Callby: cfg init_term
  977. |Purpose: Gets a character from the terminal.
  978. |Arguments:
  979. |    c is the returned character.
  980. \******************************************************************************/
  981. void ttyget(c)
  982. Schar *c;
  983. {
  984.     static Char buf[2],*next = buf;
  985.     static Int remain = 0;
  986.  
  987.     short shift, bshift, keyqptr[2];
  988.     unsigned evtcode,scan,asci;
  989.     Uchar thischar;
  990.  
  991.     while(!remain)
  992.     {
  993.         next = buf;
  994. #ifndef NO_EVENTS
  995.         if(q) {
  996.             EventRecord e;
  997.             while(!EventQueueNextEvent(q,&e) || e.evt_type != EVENT_KEYBD);    /* Another event */
  998.             shift = e.evt_kbstat;
  999.             if(KB_NUMLOCK & (shift ^ saveshift))        /* NumLock */
  1000.             {
  1001.                 *next++ = 0xaf;
  1002.                 remain++;
  1003.             }
  1004.             dosmemget(0x417,2,&bshift);
  1005.             if(setnumlk && !q->evq_cursize && !(KB_NUMLOCK & bshift)) {
  1006.                 saveshift = KB_NUMLOCK | bshift;
  1007.                 dosmemput(&saveshift,2,0x417);
  1008.             } else
  1009.                 saveshift = shift;
  1010.             evtcode = (e.evt_scancode & 0xffff);
  1011.         }
  1012.         else
  1013. #endif
  1014.         {
  1015.             union REGS regs;
  1016.             
  1017.             regs.x.ax = 0x1000;
  1018.             int86(0x16, ®s, ®s);    /* Read a character, wait */
  1019.             evtcode = (regs.x.ax & 0xffff);
  1020.             dosmemget(0x417,2,&shift);    /* Assumes curr shift state for press */
  1021.             if(KB_NUMLOCK & (shift ^ saveshift))        /* NumLock */
  1022.             {
  1023.                 *next++ = 0xaf;
  1024.                 remain++;
  1025.             }
  1026.             dosmemget(0x41a,4,keyqptr);
  1027.             if(setnumlk && (keyqptr[0] == keyqptr[1])&& !(KB_NUMLOCK & shift)) {
  1028.                 saveshift = KB_NUMLOCK | shift;
  1029.                 dosmemput(&saveshift,2,0x417);
  1030.             } else
  1031.                 saveshift = shift;
  1032.         }
  1033.         scan = evtcode >> 8;
  1034.         asci = evtcode & 0xff;
  1035.         if(evtcode == 0x0e08)        /* Rubout */
  1036.             thischar = 127;
  1037.         else if(asci > 0 && scan <= 0x35)    /* If Caps Lock on then it is Caps! */
  1038.         {
  1039.             if((KB_CAPSLOCK & shift) && asci >= 'a' && asci <= 'z')
  1040.                 asci -= 0x20;
  1041.             thischar = asci;
  1042.         }
  1043.         else if(scan == 0x39)        /* Space */
  1044.             thischar = ' ';
  1045.         else if(scan >= 0x47 && scan <= 0x53)    /* 13 characters between 0x00 and 0x0c (Keypad & Arrows) */
  1046.             thischar = ((asci == 0xe0)? 0xa0 : 0xb0) + (scan - 0x47);
  1047.         else if(evtcode == 0xe00d)    /* KpEnter */
  1048.             thischar = 0xbd;
  1049.         else if(evtcode == 0xe02f)    /* PF2 */
  1050.             thischar = 0xbe;
  1051.         else if(evtcode == 0x372a)    /* PF3 */
  1052.             thischar = 0xbf;
  1053.         else if(evtcode == 0x0300)    /* Null */
  1054.             thischar = 0;
  1055. /* 10 characters between 0x00 and 0x09 (F1 to F10) */
  1056.         else if(scan >= 0x3b && scan <= 0x44)
  1057.             thischar = 0xc0 + (scan - 0x3b);
  1058.         else if(evtcode == 0x8500)    /* F11 */
  1059.             thischar = 0xca;
  1060.         else if(evtcode == 0x8600)    /* F12 */
  1061.             thischar = 0xcb;
  1062.         else
  1063.             thischar = 0xff;        /* indicate not set */
  1064.  
  1065.         if(thischar >= 0xb0 && thischar <= 0xbf) /* shift special */
  1066.             if(KB_SHIFT & shift) thischar -= 0x10;
  1067.  
  1068.         if(thischar != 0xff)
  1069.         {
  1070.             *next++ = thischar;
  1071.             remain++;
  1072.         }
  1073.         next = buf;
  1074.     }
  1075.     *c = *((Schar *)next++);
  1076.     remain--;
  1077.     return;
  1078. }
  1079.  
  1080. /******************************************************************************\
  1081. |Routine: ttyend
  1082. |Callby: init_term ttyput
  1083. |Purpose: Terminates connection with the terminal.
  1084. |Arguments:
  1085. |    none
  1086. \******************************************************************************/
  1087. void ttyend()    /* this is a handler that restores the terminal settings at image exit */
  1088. {
  1089.     if(restored++)
  1090.         return;
  1091.     EventQueueDeInit();
  1092.     return;
  1093. }
  1094.  
  1095. void ttystart()
  1096. {
  1097. #ifndef NO_EVENTS
  1098.     q = EventQueueInit(Qsize,320,NULL);
  1099.     if(q) q->evq_drawmouse = 0;
  1100. #endif
  1101.     dosmemget(0x417,2,&saveshift);
  1102.     restored = 0;
  1103. }
  1104.  
  1105. #else        /* !GNUDOS */
  1106.  
  1107. #include "unistd.h"
  1108. #ifdef NeXT
  1109. #include <sgtty.h>
  1110. static struct sgttyb savetty;
  1111. #else
  1112. #include <termios.h>
  1113. #ifndef NO_TERMSIZE                    /* Posix doesn't have terminal size */
  1114. #ifndef sparc
  1115. #include <sys/ioctl.h>                /* Only for terminal size IOCTL */
  1116. #endif
  1117. #endif
  1118. static struct termios savetty;
  1119. #endif
  1120. #include <fcntl.h>
  1121. #include <signal.h>
  1122. #ifndef O_NDELAY                    /* Posix */
  1123. #define O_NDELAY O_NONBLOCK
  1124. #endif
  1125.  
  1126. static Int ttyfd;
  1127.  
  1128. /******************************************************************************\
  1129. |Routine: ttygetsb
  1130. |Callby: put
  1131. |Purpose: Null routine.
  1132. |Arguments:
  1133. |    ptr - physical video frame buffer base pointer.
  1134. \******************************************************************************/
  1135. void ttygetsb(ptr)
  1136. short **ptr;
  1137. {
  1138.     printf("You can't use this terminal configuration file with this image.\r\n");
  1139.     cleanup(-1);
  1140. }
  1141.  
  1142. /******************************************************************************\
  1143. |Routine: ttyscreen
  1144. |Callby: put
  1145. |Purpose: Null routine.
  1146. |Arguments:
  1147. |    row, col - where to position the cursor on the screen, zero based.
  1148. \******************************************************************************/
  1149. void ttyscreen(row,col)
  1150. Int row,col;
  1151. {
  1152. }
  1153.  
  1154. /******************************************************************************\
  1155. |Routine: ttysetsize
  1156. |Callby: init_term
  1157. |Purpose: Handles defaults for terminal size.
  1158. |Arguments:
  1159. |    nrow, ncol - the number of rows and columns on the screen.
  1160. \******************************************************************************/
  1161. void ttysetsize(nrow,ncol)
  1162. Int *nrow,*ncol;
  1163. {
  1164.     Int tmprow, tmpcol;
  1165. #ifndef NO_TERMSIZE
  1166.     struct winsize ttysiz;
  1167. #endif
  1168.  
  1169.     if(!*nrow || !*ncol)
  1170.     {
  1171.         tmprow = 24;
  1172.         tmpcol = 80;
  1173. #ifndef NO_TERMSIZE
  1174.         ttysiz.ws_row = 0;
  1175.         ttysiz.ws_col = 0;
  1176.         ioctl(ttyfd,TIOCGWINSZ,&ttysiz);
  1177.         if(ttysiz.ws_row > 0)
  1178.             tmprow = ttysiz.ws_row;
  1179.         if(ttysiz.ws_col > 0)
  1180.             tmpcol = ttysiz.ws_col;
  1181. #endif
  1182.         if(!*nrow)
  1183.             *nrow = tmprow;
  1184.         if(!*ncol)
  1185.             *ncol = tmpcol;
  1186.     }
  1187. }
  1188.  
  1189. /******************************************************************************\
  1190. |Routine: ring_bell
  1191. |Callby: init_term
  1192. |Purpose: Handles special bell-ringing for brain-dead terminals.
  1193. |Arguments:
  1194. |    none
  1195. \******************************************************************************/
  1196. void ring_bell()
  1197. {
  1198. }
  1199.  
  1200. /******************************************************************************\
  1201. |Routine: ttyput
  1202. |Callby: put
  1203. |Purpose: Puts characters to the terminal.
  1204. |Arguments:
  1205. |    c is the string to send to the terminal.
  1206. \******************************************************************************/
  1207. void ttyput(c)
  1208. Char *c;
  1209. {
  1210.     Int i;
  1211.  
  1212.     if(!(i = strlen(c)))
  1213.         return;
  1214.     while(i > 64)
  1215.     {
  1216.         write(ttyfd,c,64);
  1217.         c += 64;
  1218.         i -= 64;
  1219.     }
  1220.     if(i)
  1221.         write(ttyfd,c,i);
  1222. }
  1223.  
  1224. /******************************************************************************\
  1225. |Routine: ttyget
  1226. |Callby: cfg init_term
  1227. |Purpose: Gets a character from the terminal.
  1228. |Arguments:
  1229. |    c is the returned character.
  1230. \******************************************************************************/
  1231. void ttyget(c)
  1232. Schar *c;
  1233. {
  1234.     static Char buf[8],*next = buf;
  1235.     static Int remain = 0;
  1236.  
  1237.     if(!remain)
  1238.     {
  1239.         remain = read(ttyfd,buf,8);
  1240.         next = buf;
  1241.     }
  1242.     *c = *((Schar *)next++);
  1243.     remain--;
  1244. }
  1245.  
  1246. /******************************************************************************\
  1247. |Routine: ttyend
  1248. |Callby: init_term ttyput
  1249. |Purpose: Terminates connection with the terminal.
  1250. |Arguments:
  1251. |    none
  1252. \******************************************************************************/
  1253. void ttyend()    /* this is a handler that restores the terminal settings at image exit */
  1254. {
  1255.     if(restored++)
  1256.         return;
  1257. #ifdef NeXT
  1258.     ioctl(ttyfd,TIOCSETP,&savetty);
  1259. #else
  1260.     tcsetattr(ttyfd,TCSANOW,&savetty);
  1261. #endif
  1262.     close(ttyfd);
  1263.     signal(SIGINT,SIG_DFL);
  1264.     return;
  1265. }
  1266.  
  1267. /******************************************************************************\
  1268. |Routine: ttystart
  1269. |Callby: init_term ttyput
  1270. |Purpose: Initiates connection with the terminal.
  1271. |Arguments:
  1272. |    none
  1273. \******************************************************************************/
  1274. void ttystart()
  1275. {
  1276. #ifdef NeXT
  1277.     struct sgttyb newtty;
  1278. #else
  1279.     struct termios newtty;
  1280.     Char termname[L_ctermid];
  1281. #endif
  1282.     Int i;
  1283.  
  1284. #ifdef NeXT
  1285.     if((ttyfd = open("/dev/tty",O_RDWR)) < 0)
  1286.     {
  1287.         printf("Unable to open terminal /dev/tty.\n");
  1288. #else
  1289.     if((ttyfd = open(ctermid(termname),O_RDWR)) < 0)
  1290.     {
  1291.         printf("Unable to open terminal %s.\n",termname);
  1292. #endif
  1293.         exit(1);
  1294.     }
  1295. #ifdef NeXT
  1296.     if(ioctl(ttyfd,TIOCGETP,&savetty) == -1)
  1297. #else
  1298.     if(tcgetattr(ttyfd,&savetty) == -1)
  1299. #endif
  1300.     {
  1301.         printf("Unable to read terminal characteristics.\n");
  1302.         exit(1);
  1303.     }
  1304.     newtty = savetty;
  1305. #ifdef NeXT
  1306.     newtty.sg_flags |= RAW | CBREAK;
  1307.     newtty.sg_flags &= ~(CRMOD | ECHO);
  1308.     if(ioctl(ttyfd,TIOCSETP,&newtty) == -1)
  1309. #else
  1310.     newtty.c_lflag &= ~(ICANON | ISIG | ECHO);
  1311.     newtty.c_oflag &= ~OPOST;
  1312.     newtty.c_iflag &= ~(INLCR | ICRNL | ISTRIP | BRKINT); /* IUCLC */
  1313.     newtty.c_cflag |= HUPCL;
  1314. /*    newtty.c_cflag &= ~CLOCAL;*/
  1315.     for(i = 0;i < 16;i++)
  1316.         newtty.c_cc[i] = 0;
  1317.     newtty.c_cc[VMIN] = 5;    /* terminate io if 5 chars arrive... */
  1318.     newtty.c_cc[VTIME] = 1;    /* ...or 10 ms elapse */
  1319.     if(tcsetattr(ttyfd,TCSANOW,&newtty) == -1)
  1320. #endif
  1321.     {
  1322.         printf("Unable to set terminal to raw mode.\r\n");
  1323.         perror("ttyput");
  1324.         exit(1);
  1325.     }
  1326.     signal(SIGINT,ttyend);
  1327.     restored = 0;
  1328. }
  1329.  
  1330. /******************************************************************************\
  1331. |Routine: ttychk
  1332. |Callby: load_file
  1333. |Purpose: Checks for a character waiting, and returns it.
  1334. |Arguments:
  1335. |    none
  1336. \******************************************************************************/
  1337. Int ttychk()
  1338. {
  1339.     Int flags,retval;
  1340.     Char buf;
  1341.     
  1342.     retval = -1;
  1343.     if((flags = fcntl(ttyfd,F_GETFL,0)) != -1)
  1344.         if(fcntl(ttyfd,F_SETFL,flags | O_NDELAY) != -1)
  1345.         {
  1346.             if(read(ttyfd,&buf,1) == 1)
  1347.                 retval = buf;
  1348.             fcntl(ttyfd,F_SETFL,flags);
  1349.         }
  1350.     return(retval);
  1351. }
  1352.  
  1353. #endif        /* GNUDOS */
  1354.  
  1355. #endif        /* GNUOS2 */
  1356.  
  1357. #endif        /* WIN32 */
  1358.  
  1359. #endif        /* VMS */
  1360.  
  1361. /******************************************************************************\
  1362. |Routine: cleanup
  1363. |Callby: cfg imalloc init_term journal main parse_fnm restore_par slip_message
  1364. |Purpose: Does all cleanup on image exit.
  1365. |Arguments:
  1366. |    STATUS - the value to pass to exit().
  1367. \******************************************************************************/
  1368. void cleanup(status)
  1369. Int status;
  1370. {
  1371.     ttyend();
  1372. #ifdef VMS
  1373.     exit((status < 0)? 0 : 1);
  1374. #else
  1375.     exit(status);
  1376. #endif
  1377. }
  1378.  
  1379.